const fs = require('fs');
const { resolve, dirname } = require('path');
const request = require("request");


class Watcher {

  /**
   * @type {string}
   */
  url;
  me = resolve("./index.js");
  /**
   * @type {fs.FSWatcher}
   */
  hm;
  /**
   * @type {fs.FSWatcher}
   */
  hp;
  /**
   * @type {string[]}
   */
  files = [];
  existFilePath = resolve("./exist.json");
  /** @type {any} */
  tmp = {};

  constructor () {
    this.init();
  }
  async init() {
    this.getExistFile();
    const config = require("./config.json");
    this.url = config.url;
    const path = resolve(config.path);
    const efs = this.dir(path);
    for (let i = 0; i < efs.length; i++) {
      await this.uploadFile(efs[i]);
    }

    this.hp = fs.watch(path, { recursive: true }, async (e, b) => {
      const tp = resolve(path, b);
      if (fs.existsSync(tp) && fs.statSync(tp).isFile() && !this.tmp[tp]) {
        this.tmp[tp] = true;
        const r = await this.uploadFile(tp);
        delete this.tmp[tp];
        console.log(0, r);
      }
    });
  }
  getExistFile() {
    let files;
    if (fs.existsSync(this.existFilePath) && fs.statSync(this.existFilePath).isFile()) {
      try {
        files = require(this.existFilePath);
      } catch (error) {
        fs.writeFileSync(this.existFilePath, JSON.stringify([]));
      }
    } else {
      fs.writeFileSync(this.existFilePath, JSON.stringify([]));
    }
    if (Array.isArray(files)) {
      files.forEach(f => {
        if (typeof f == "string") {
          this.files.push(f);
        }
      });
    } else {
      this.getExistFile();
    }
  }
  /** @param {string} p */
  isFile(p) {
    const ret = fs.existsSync(p) && fs.statSync(p).isFile();
    return ret;
  }
  /**
   * @param {string} p
   */
  dir(p) {
    /** @type {string[]} */
    const ret = [];
    const rs = fs.readdirSync(p);
    if (Array.isArray(rs)) {
      rs.forEach(a => {
        const tp = resolve(p, a);
        if (this.isFile(tp)) {
          if (this.files.indexOf(tp) < 0) { ret.push(tp); }
        } else {
          this.dir(tp).forEach(b => { ret.push(b); });
        }
      });
    }
    return ret;
  }

  /**
   * @param {string} fileName
   */
  uploadFile(fileName) {
    return new Promise((ret) => {
      const path = resolve(fileName);
      if (this.isFile(path) && this.files.indexOf(path) < 0) {
        const formData = {
          imgFile: fs.createReadStream(path),
          path: dirname(path)
        };
        // @ts-ignore
        request({ method: 'POST', url: this.url, headers: { 'Content-Type': 'multipart/form-data' }, formData }, (error, response, body) => {
          if (error) {
            ret(error);
          } else {
            try {
              const r = JSON.parse(body);
              if (path.replace(/\\/g, "/").indexOf(r) >= 0) {
                this.files.push(path);
                fs.writeFileSync(this.existFilePath, JSON.stringify(this.files));
                ret(undefined);
              } else { ret(r); }
            } catch (error) {
              ret(body);
            }
          }
        });
      } else {
        ret({ msg: "文件以上传或不存在", path });
      }
    });
  }
}
console.clear();
const t = new Watcher(); //  

// class Watcher extends events.EventEmitter {
//   private readonly watcherDir: string;
//   private readonly processedDir: string;
//   static Watcher: events = new events.EventEmitter();;

//   constructor (watcherDir: string, processedDir: string) {
//     super();
//     this.watcherDir = watcherDir;
//     this.processedDir = processedDir;
//   }
//   public watch() {
//     fs.readdir(this.watcherDir, function (err, files) {
//       console.log(err, files);
//       if (err) throw err;
//       files.forEach(function (value) {
//         console.log(value);
//         watcher.emit('process', value);
//       });
//     });
//   }
//   public start() {
//     const watcher = this;
//     fs.watchFile(this.watcherDir, function () {
//       console.log(arguments);
//       watcher.watch();
//     });
//   }
// }

// const watcher = new Watcher('./watcher', './processed');
// watcher.on('process', function (file: string) {
//   console.log(file);
//   const watchFile = this.watcherDir + '/' + file;
//   const processedFile = this.processedDir + '/' + file.toLowerCase();
//   fs.rename(watchFile, processedFile, function (err) {
//     if (err) throw err;
//   });
// });
